package junk;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;

import processing.core.PApplet;


public class Backend extends Main1 {
	private static final long serialVersionUID = 1L;
	public static float x = WIDTH1*.25f;
	public static float y = HEIGHT1*-.4f;
	public static boolean removeZeros = true;
	public static boolean showFullSet = true;
	public float zeroCutoff;
	public PApplet parent;
	
	public void initialize( Main1 p)
	{
		p.loadDisplay2();
		parent = p;
		datasetView();
		
	}
	public void datasetView()
	{
		parent.scale(parent.width/WIDTH1, parent.height/HEIGHT1);
		
		if(activeItem instanceof Protein)
		{
			Protein dataset = (Protein) activeItem;
			if(dataset.type.equals("Group"))
			{
				parent.textFont(font32);
				parent.textAlign(Main1.CENTER);
				parent.text(dataset.name, x, y);
				float containerHeight = (float) (HEIGHT1*.8/dataset.children.size());
				for(int i = 0; i< dataset.children.size(); i++)
				{
					if(showFullSet) 
					{
						float[] minMax = distribution(dataset.children.get(i), Gene.geneList, x - 250, y + containerHeight*i, 500, containerHeight);
						distributionSubset(dataset.children.get(i), firstAnnotation.genes, x - 250, y + containerHeight*i, 500, containerHeight, minMax[0], minMax[1]);
					}
					else
						distribution(dataset.children.get(i), firstAnnotation.genes, x - 250, y + containerHeight*i, 500, containerHeight);
				}				
				parent.textAlign(Main1.LEFT);
				parent.text("Show Full Set Trace", x - 200, y + HEIGHT1*.8f + 35);
				parent.noFill();
				parent.rect(x-225, y + HEIGHT1*.8f+5 + 20, 25,25);
				if(showFullSet)
				{
					parent.line(x-237.5f, y + HEIGHT1*.8f+12.5f, x-212.5f, y + HEIGHT1*.8f+37.5f);
					parent.line(x-237.5f, y + HEIGHT1*.8f+37.5f, x-212.5f, y + HEIGHT1*.8f+12.5f);
				}
			}
		}
		parent.scale(WIDTH1/parent.width, HEIGHT1/parent.height);
	}
	public float[] distribution( Protein protein, Gene[] genes, float sX, float sY, float containerWidth, float containerHeight)
	{
		float[] dataValues = new float[genes.length];
		int columnInData = protein.columnInData;
		int dataset = -1;		
		for( int z = 0; z< ReadGenes.datasets.length; z++)
		{
			if(protein.annotation.equals(ReadGenes.datasets[z]))
				dataset = z;
			else if(protein.set.equals(ReadGenes.datasets[z]))
				dataset = z;
		}	
		for(int i = 0; i< dataValues.length; i++)
		{
			if(protein.type.equals("Raw"))
			{
				if(percentValues)
					dataValues[i] = genes[i].percentExpressionConditions.get(dataset)[columnInData];
				else
					dataValues[i] = genes[i].expressionConditions.get(dataset)[columnInData];
			}
			else if(protein.type.equals("P-Value"))
				dataValues[i] = (float) Math.log10(genes[i].expressionConditions.get(dataset)[columnInData]);
			else if(protein.type.equals("Boolean"))
			{
				BooleanGroup b = (BooleanGroup) protein;
				dataValues[i] = (float) b.percentExpression( i);
				percentValues = true;
				dataset = -2;
			}
		}
		Arrays.sort(dataValues);
		float min = dataValues[(int)((dataValues.length-1)*.01)];
		float max = dataValues[(int)((dataValues.length-1)*.99)];
		int numBins = 100;
		float interval = (max-min)/(float)(numBins-1);
		int[] counts = new int[numBins];
		float currentCutoff = min;
		int currentBin = 0;
		for(int i = 0; i< dataValues.length; i++)
		{			
			while(dataValues[i] > currentCutoff  && currentBin < (numBins - 1))
			{
				currentCutoff += interval;
				currentBin++;
			}
			counts[currentBin] ++;
		}
		
		int[] countsCopy = new int[numBins];
		for(int i= 0; i< numBins; i++)
			countsCopy[i] = counts[i];
		Arrays.sort(countsCopy);
		int maxCount = countsCopy[numBins - 1];
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 2];
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 3];	
		boolean[] flags = new boolean[numBins];
		for(int i = 0; i< numBins; i++)
			flags[i] = false;
		
		if(removeZeros)
		{
			maxCount = countsCopy[numBins - 2];
			for(int i= 0; i< numBins; i++)
				if(counts[i] > maxCount)
				{
					counts[i]= maxCount;
					flags[i] =true;					
				}
		}

		//display
		float baseline = sY + containerHeight;
		parent.stroke(128,128,255);
		parent.line(sX, baseline, sX + containerWidth, baseline);
		if(!showFullSet)
		{
			parent.stroke(0,0,255);
			parent.noFill();
		}
		else
		{
			parent.noStroke();
			parent.fill(255,227, 67, 25);
		}
		parent.beginShape();
		for(int i = 1; i<numBins-1; i++)
		{
			float x = sX + (((float)i/(float)numBins)*(containerWidth));
			float y = baseline - containerHeight*((float)counts[i]/(float)maxCount);
			parent.vertex(x,y);
			if(flags[i]) 
			{
				parent.stroke(255,0,0);
				parent.ellipse(x,y,3,3);
				if(!showFullSet) parent.stroke(0,0,255);
				else parent.noStroke();
			}
			if(showFullSet && (i == numBins -2 || i==1)) parent.vertex(x,baseline);
		}
		parent.endShape();
		if(containerHeight > 100) parent.textFont(font32);
		else parent.textFont(font15);
		parent.textAlign(Main1.LEFT);
		parent.fill(255,100);
		parent.text(protein.name, sX, baseline);
		parent.textAlign(Main1.CENTER);
		float[] minMax = {min, max, maxCount};
		return minMax;
	}
	public void distributionSubset( Protein protein, Gene[] genes, float sX, float sY, float containerWidth, float containerHeight, float min, float max)
	{
		float[] dataValues = new float[genes.length];
		int columnInData = protein.columnInData;
		int dataset = -1;		
		for( int z = 0; z< ReadGenes.datasets.length; z++)
		{
			if(protein.annotation.equals(ReadGenes.datasets[z]))
				dataset = z;
			else if(protein.set.equals(ReadGenes.datasets[z]))
				dataset = z;
		}	
		for(int i = 0; i< dataValues.length; i++)
		{
			if(protein.type.equals("Raw"))
			{
				if(percentValues)
					dataValues[i] = genes[i].percentExpressionConditions.get(dataset)[columnInData];
				else
					dataValues[i] = genes[i].expressionConditions.get(dataset)[columnInData];
			}
			else if(protein.type.equals("P-Value"))
				dataValues[i] = (float) Math.log10(genes[i].expressionConditions.get(dataset)[columnInData]);
			else if(protein.type.equals("Boolean"))
			{
				BooleanGroup b = (BooleanGroup) protein;
				dataValues[i] = (float) b.percentExpression( i);
				percentValues = true;
				dataset = -2;
			}
		}
		Arrays.sort(dataValues);
		int numBins = 100;
		float interval = (max-min)/(float)(numBins-1);
		int[] counts = new int[numBins];
		float currentCutoff = min;
		int currentBin = 0;
		for(int i = 0; i< dataValues.length; i++)
		{			
			while(dataValues[i] > currentCutoff  && currentBin < (numBins - 1))
			{
				currentCutoff += interval;
				currentBin++;
			}
			counts[currentBin] ++;
		}
		
		int[] countsCopy = new int[numBins];
		for(int i= 0; i< numBins; i++)
			countsCopy[i] = counts[i];
		Arrays.sort(countsCopy);
		
		boolean[] flags = new boolean[numBins];
		for(int i = 0; i< numBins; i++)
			flags[i] = false;
		
		int maxCount = countsCopy[numBins - 1];
		
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 2];
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 3];	
		
		if(removeZeros)
		{
			maxCount = countsCopy[numBins - 2];
			for(int i= 0; i< numBins; i++)
				if(counts[i] > maxCount)
				{
					counts[i]= maxCount;
					flags[i] =true;					
				}
		}		
		
		//display
		float baseline = sY + containerHeight;
		parent.stroke(128,128,255);
		parent.line(sX, baseline, sX + containerWidth, baseline);	
		parent.stroke(0,0,255);
		parent.noFill();
		parent.beginShape();
		for(int i = 1; i<numBins-1; i++)
		{
			float x = sX + (((float)i/(float)numBins)*(containerWidth));
			float y = baseline - containerHeight*((float)counts[i]/(float)maxCount);
			parent.vertex(x,y);
			if(flags[i]) 
			{
				parent.stroke(255,0,0);
				parent.ellipse(x,y,3,3);
				parent.stroke(0,0,255);
			}
		}
		parent.endShape();
		if(containerHeight > 100) parent.textFont(font32);
		else parent.textFont(font15);
		parent.textAlign(Main1.LEFT);
		parent.fill(255,100);
		parent.text(protein.name, sX, baseline);
		parent.textAlign(Main1.CENTER);
	}
}


